package cn.duckerkj.util;

import java.text.ParseException;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ValidatorsUtils {

	/**
	 * 电话号码的正则表达式。
	 */
	// private static final String REGEX_PHONE_NUMBER =
	// "(([\\(（]\\d+[\\)）])?|(\\d+[-－]?)*)\\d+";

	/**
	 * 移动手机号码的正则表达式。
	 */
	private static final String REGEX_CHINA_MOBILE = "1(3[4-9]|4[7]|5[012789]|8[278])\\d{8}";

	/**
	 * 联通手机号码的正则表达式。
	 */
	private static final String REGEX_CHINA_UNICOM = "1(3[0-2]|5[56]|8[56])\\d{8}";

	/**
	 * 电信手机号码的正则表达式。
	 */
	private static final String REGEX_CHINA_TELECOM = "(?!00|015|013)(0\\d{9,11})|(1(33|53|80|89)\\d{8})";

	/**
	 * 手机号码的正则表达式。
	 */
	private static final String REGEX_MOBILE = "^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$";

	/**
	 * 用于匹配多个数字之间用逗号分隔，且第一个和最后一个字符必须是数字。
	 */
	private static final String REGEX_NUMBERANDCOMMA = "^\\d([\\d,]*\\d)?$";

	/**
	 * 匹配身份证号码
	 */
	private static final String ID_NUMBER = "^\\d{15}(\\d{2}[a-z0-9A-Z])?$";

	/**
	 * 电子邮箱或者电子邮件地址
	 */
	private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";

	/**
	 * 是否为小数
	 */
	private static final String REGEX_DECIMAL = "^\\d+\\.\\d+$";

	/**
	 * 密码正则
	 */
	private static final String REGEX_PASSWORD = "^[\\@A-Za-z0-9\\!\\#\\$\\%\\^\\&\\*\\.\\~]{6,16}$";
	

	/**
	 * 字符串是否为Empty，null和空格都算是Empty
	 * 
	 * @param str
	 *            字符串
	 * @return true/false
	 */
	public static boolean isEmpty(String str) {
		return str == null || str.trim().length() == 0;
	}

	/**
	 * 是否为数字的字符串。
	 * 
	 * @param str
	 *            字符串
	 * @return true/false
	 */
	public static boolean isNumber(String str) {
		if (isEmpty(str)) {
			return false;
		}

		for (int i = 0; i < str.length(); i++) {
			if (str.charAt(i) > '9' || str.charAt(i) < '0') {
				return false;
			}
		}
		return true;
	}

	/**
	 * 是否是固定范围内的数字的字符串
	 * 
	 * @param str
	 * @param min
	 * @param max
	 * @return true/false
	 */
	public static boolean isNumber(String str, int min, int max) {
		if (!isNumber(str)) {
			return false;
		}

		int number = Integer.parseInt(str);
		return number >= min && number <= max;
	}

	/**
	 * 判断字符是否为符合精度要求的整数或浮点数。
	 * 
	 * @param str
	 *            字符串
	 * @param fractionNum
	 *            小数部分的最多允许的位数
	 * @return 若为整数或浮点数则返回 <code>true</code>, 否则返回 <code>false</code>
	 */
	public static boolean isNumeric(String str, int fractionNum) {
		if (isEmpty(str)) {
			return false;
		}
		// 整数或浮点数
		String regex = "(\\+|-){0,1}(\\d+)([.]?)(\\d{0," + fractionNum + "})";
		return Pattern.matches(regex, str);
	}

	/**
	 * 是否是合法的日期字符串
	 * 
	 * @param str
	 *            日期字符串
	 * @return 是true，否则false
	 * @throws ParseException
	 */
	public static boolean isDate(String str) {
		if (isEmpty(str) || str.length() > 10) {
			return false;
		}
		String[] items = str.split("-");
		if (items.length != 3) {
			return false;
		}
		if (!isNumber(items[0], 1900, 9999) || !isNumber(items[1], 1, 12)) {
			return false;
		}
		int year = Integer.parseInt(items[0]);
		int month = Integer.parseInt(items[1]);
		return isNumber(
				items[2],
				1,
				DateUtils.getMaxDayOfMonth(String.valueOf(year),
						String.valueOf(month)));
	}

	/**
	 * 获取6位数字验证码
	 * 
	 * @return
	 */
	public static String getValidateCode() {
		char[] codeSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
				'9' };
		// 创建一个随机数生成器类
		Random random = new Random();
		StringBuffer randomCode = new StringBuffer();
		// 随机产生codeCount数字的验证码。
		for (int i = 0; i < 6; i++) {
			// 得到随机产生的验证码数字。
			String strRand = String.valueOf(codeSequence[random.nextInt(10)]);
			// 将产生的四个随机数组合在一起。
			randomCode.append(strRand);
		}
		return randomCode.toString();
	}

	/**
	 * 获取4位数字验证码
	 * 
	 * @return
	 */
	public static String getValidateFourCode() {
		char[] codeSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
				'9' };
		// 创建一个随机数生成器类
		Random random = new Random();
		StringBuffer randomCode = new StringBuffer();
		// 随机产生codeCount数字的验证码。
		for (int i = 0; i < 4; i++) {
			// 得到随机产生的验证码数字。
			String strRand = String.valueOf(codeSequence[random.nextInt(10)]);
			// 将产生的四个随机数组合在一起。
			randomCode.append(strRand);
		}
		return randomCode.toString();
	}

	/**
	 * 判断是否是手机号码
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isPhoneNumber(String str) {
		// Regex for checking phone number
		// 最近中国电信分到新号段170,177,联通分到了176,移动分到了178号段.
		// 14号段以前为上网卡专属号段，如中国联通的是145，中国移动的是147等等。
		if (ValidatorsUtils.isEmpty(str)) {
			return false;
		}
		return isRegexMatch(str, REGEX_CHINA_MOBILE)
				|| isRegexMatch(str, REGEX_CHINA_UNICOM)
				|| isRegexMatch(str, REGEX_CHINA_TELECOM)
				|| isRegexMatch(str, REGEX_MOBILE) || str.startsWith("170")
				|| str.startsWith("177") || str.startsWith("176")
				|| str.startsWith("178") || str.startsWith("145")
				|| str.startsWith("147");
	}

	/**
	 * 判断字符串是否匹配了正则表达式。
	 * 
	 * @param str
	 *            字符串
	 * @param regex
	 *            正则表达式
	 * @return true/false
	 */
	public static boolean isRegexMatch(String str, String regex) {
		return str != null && str.matches(regex);
	}

	/**
	 * 判断是否是yyyy-MM-dd HH:mm:ss 格式的字符串
	 * 
	 * @param s
	 * @return
	 */
	public static boolean isValidDateHMS(String s) {
		if (null != s) {
			if (s.endsWith(".0")) {
				s = s.trim().substring(0, s.trim().indexOf(".0"));
			}
			String eL = "^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s(((0?[0-9])|([1][0-9])|([2][0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$";
			Pattern p = Pattern.compile(eL);
			Matcher m = p.matcher(s);
			boolean b = m.matches();
			if (b) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断是否是移动手机号码
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isPhoneMobile(String str) {
		// Regex for checking phone number
		return isRegexMatch(str, REGEX_CHINA_MOBILE) || str.startsWith("183")
				|| str.startsWith("182") || str.startsWith("184")
				|| str.startsWith("187") || str.startsWith("188")
				|| str.startsWith("153");
	}

	/**
	 * 判断是否是电子邮件
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isEmail(String str) {
		return isRegexMatch(str, REGEX_EMAIL);
	}

	/**
	 * 获取3位随机数
	 * 
	 * @return
	 */
	public static String getThreeRandomCode() {
		char[] codeSequence = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
				'9' };
		// 创建一个随机数生成器类
		Random random = new Random();
		StringBuffer randomCode = new StringBuffer();
		// 随机产生codeCount数字的验证码。
		for (int i = 0; i < 3; i++) {
			// 得到随机产生的验证码数字。
			String strRand = String.valueOf(codeSequence[random.nextInt(10)]);
			// 将产生的四个随机数组合在一起。
			randomCode.append(strRand);
		}
		return randomCode.toString();
	}

	/**
	 * 判断是否是身份证号
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isIDNumber(String str) {
		// Regex for checking phone number
		return isRegexMatch(str, ID_NUMBER);
	}

	/**
	 * 用于匹配多个数字之间用逗号分隔，且第一个和最后一个字符必须是数字。
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumberAndComma(String str) {
		return isRegexMatch(str, REGEX_NUMBERANDCOMMA);
	}

	/**
	 * 判断传入的字段是否为空或null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static String isReplaceDefault(String str1, String str2) {
		if (!ValidatorsUtils.isEmpty(str1)) {
			return str1;
		}
		return str2;
	}

	/**
	 * 判断传入的字段是否为null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static Long isReplaceDefault(Long l1, Long l2) {
		if (null != l1) {
			return l1;
		}
		return l2;
	}

	/**
	 * 判断传入的字段是否为null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static Long isReplaceDefault(Integer l1, Long l2) {
		if (null != l1) {
			return Long.parseLong(l1.toString());
		}
		return l2;
	}

	/**
	 * 判断传入的字段是否为null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static Integer isReplaceDefault(Integer l1, Integer l2) {
		if (null != l1) {
			return l1;
		}
		return l2;
	}

	/**
	 * 判断传入的字段是否为null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static String isReplaceDefault(Integer l1, String l2) {
		if (null != l1) {
			return l1.toString();
		}
		return l2;
	}

	/**
	 * 判断传入的字段是否为null 是则返回第二个参数
	 * 
	 * @return
	 */
	public static Double isReplaceDefault(Double l1, Double l2) {
		if (null != l1) {
			return l1;
		}
		return l2;
	}

	/**
	 * 是否为小数的字符串。
	 * 
	 * @param str
	 *            字符串
	 * @return true/false
	 */
	public static boolean isDecimal(String str) {
		return isRegexMatch(str, REGEX_DECIMAL);
	}

	/**
	 * 是否为小数的字符串。
	 * 
	 * @param str
	 *            字符串
	 * @return true/false
	 */
	public static boolean isRegPassword(String str) {
		return isRegexMatch(str, REGEX_PASSWORD);
	}

}